//
//  NKTodaySleepWeeklyChartView.swift
//  Nokia
//
//  Created by 易先生 on 2022/4/12.
//

import UIKit
import MYModule
import RxCocoa
import RxSwift
import Charts




open class HeartRateChartView: View {
    
    public private(set) var selectIndex = PublishSubject<Int?>()
    
    public var max: Double = 110 {
        didSet {
            self.chartView.max = Int(max)
        }
    }
    public var min: Double = 50 {
        
        didSet {
            
            self.chartView.min = Int(min)
            
        }
        
    }
    public var verticals: [Int] = [200, 150, 100, 50, 0] {
        
        didSet {
            self.verticalView.verticals = verticals.map({ "\($0)" })
        }
        
    }
   
    public var lineColor: UIColor = UIColor.assist_EEEEEE
    public var lineNumber: Int = 4 {
        
        didSet {
            
            self.setNeedsDisplay()
            
        }
        
    }
    public var type: HeartType = .day
    
    
    open override func makeUI() {
        super.makeUI()
        
        self.addSubview(horizontalView)
        self.addSubview(verticalView)
        self.addSubview(bgLineView)
        self.addSubview(chartView)
        
        verticalView.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(-6)
            make.leading.equalToSuperview()
            make.bottom.equalTo(horizontalView.snp.top)
        }
        
        bgLineView.snp.makeConstraints { make in
            make.bottom.top.leading.trailing.equalTo(chartView)
        }
        
        chartView.snp.makeConstraints { make in
            
            make.left.equalTo(verticalView.snp.right).offset(10)
            make.top.trailing.equalToSuperview()
            make.height.equalTo(112)
            make.bottom.equalTo(horizontalView.snp.top).offset(-6)
            
            
        }
        
        horizontalView.snp.makeConstraints { make in
            
            make.leading.equalTo(chartView.snp.leading)
            make.trailing.equalTo(chartView.snp.trailing)
            make.height.equalTo(12)
            make.bottom.equalToSuperview()
        }
        
    }
    
    
    public func bind(barDatas: [HeartBarData]?,
                     horizontalTitles: [String],
                     YAxisMaxValue: Int,
                     YAxisMinValue: Int = 0,
                     YAxisLineCount: Int) {
        
        // x 轴
        self.horizontalView.titles = horizontalTitles
        
        // 根据最大值最小值确定Y轴
        self.verticals = calculaVerticals(max: YAxisMaxValue, min: YAxisMinValue, count: YAxisLineCount)
        self.lineNumber = YAxisLineCount
        
        // 数据
        self.chartView.barDatas = barDatas
        
    }
    
    func calculaVerticals(max: Int, min: Int, count: Int) ->[Int] {
        
        if count <= 2 {
            return [max]
        }
        
        let aHeightRange = (max - min)/count
        
        return (0 ..< count + 1).map { max - aHeightRange * $0 }
        
    }
    
    
    public func slider(_ point: CGPoint) {
        
        self.layoutIfNeeded()
        
        debugPrint("point = \(point)")
        
        var chartPoint = self.convert(point, to: chartView)
        let width = chartView.frame.width
        
        chartPoint.x = chartPoint.x - chartView.frame.minX
        
        if chartPoint.x < 0 {
            selectIndex.onNext(nil)
            return
            
        }
        
        guard let barData = chartView.barDatas, !barData.isEmpty else {
            selectIndex.onNext(nil)
            return
        }
        
        if chartPoint.x > width {
            chartPoint.x = width
        }
        
        var x = chartPoint.x
        let trun = x.truncatingRemainder(dividingBy: chartView.barWidth)
        
        if trun > 0 {
            x = chartPoint.x - trun + chartView.barWidth
        }
        
        let location: Int = Int(x/width * CGFloat(barData.count))
        
        debugPrint("point = \(chartPoint), width = \(width), location = \(location)")
        
        selectIndex.onNext(location)
        
    }
    
    open override func layoutSubviews() {
        super.layoutSubviews()
        bgLineView.drawDottedLine(lineNumber: lineNumber, lineColor: lineColor)
    }
    
    //垂直方向视图
    private lazy var verticalView: HeartRateChartVerticalView = {
        let verticalView = HeartRateChartVerticalView()
        return verticalView
    }()
    
    //背景线条
    private lazy var bgLineView: View = {
        let bgLineView = View()
        return bgLineView
    }()
    
    public lazy var horizontalView: HorizontalTitleView = {
        let horizontalView = HorizontalTitleView()
        return horizontalView
    }()
    
    public lazy var chartView: BarChartView = {
        let barChartView = BarChartView()
        return barChartView
    }()
    
    
}


public extension HeartRateChartView {
    
    class BarView: View {
        
        var max: Int = 110
        var min: Int = 50
        var dataValue: HeartBarDataValue?
        
        public override func layoutSubviews() {
            super.layoutSubviews()
            
            layer.cornerRadius = self.frame.width/2.0
            
        }
        
    }
    
    
    class BarChartCollectionCell: CollectionViewCell {
        
        var max: Int = 110
        var min: Int = 50
        var barWidth: CGFloat = 5.0
        
        var barData: HeartBarData? {
            
            didSet {
                
              
                drawBar(dayTimeBar, dataValue: barData?.dayTime, barMax: max, barMin: min, barWidth: barWidth)
                drawBar(sleepBar, dataValue: barData?.sleeping, barMax: max, barMin: min, barWidth: barWidth)
                drawBar(trainingBar, dataValue: barData?.training, barMax: max, barMin: min, barWidth: barWidth)
                
            }
        }
        
        /// 更新 bar 显示位置
        func drawBar(_ barView: BarView, dataValue: HeartBarDataValue?, barMax: Int, barMin: Int, barWidth: Double) {
            
            let max = barMax
            let min = barMin
            let range: Double = Double(max - min)
            
            barView.max = max
            barView.min = min
            barView.dataValue = dataValue
            
            guard let dataValue = dataValue, dataValue.high > 0 else {
                barView.isHidden = true
                return
            }
            
            barView.isHidden = false
            
            let barRange = dataValue.high - dataValue.low
            
            if barRange != 0 {
                
                let heightMu = 1 - barRange/range
                let bottomMu = (Double(max) - dataValue.low)/Double(max - min)
                
                barView.snp.remakeConstraints { make in
                    
                    make.centerX.equalToSuperview()
                    make.width.equalTo(barWidth)
                    make.bottom.equalToSuperview().multipliedBy(bottomMu)
                    make.height.equalToSuperview().multipliedBy(heightMu)
                }
                
            } else {
                
                // 显示一个点
                let height = barWidth
                let bottomMu = (Double(max) - (dataValue.high - barWidth/2.0))/Double(max - min)
                
                barView.snp.remakeConstraints { make in
                    
                    make.centerX.equalToSuperview()
                    make.width.equalTo(barWidth)
                    make.bottom.equalToSuperview().multipliedBy(bottomMu)
                    make.height.equalTo(height)
                }
            }
  
        }
        
        private var dayTimeBar = BarView()
        private var sleepBar = BarView()
        private var trainingBar = BarView()
        
        public override func makeUI() {
            super.makeUI()
            
            dayTimeBar.backgroundColor = UIColor.HeartRate.theme
            sleepBar.backgroundColor = UIColor.Sleep.theme
            trainingBar.backgroundColor = UIColor.GPSTraining.theme
            
            contentView.addSubview(dayTimeBar)
            contentView.addSubview(sleepBar)
            contentView.addSubview(trainingBar)
            
            dayTimeBar.snp.makeConstraints { make in
                
                make.bottom.equalToSuperview().multipliedBy(0.75)
                make.height.equalToSuperview().multipliedBy(0.5)
                make.centerX.equalToSuperview()
                make.width.equalToSuperview()
                
            }
            
            sleepBar.snp.makeConstraints { make in
                make.bottom.equalToSuperview().multipliedBy(0.75)
                make.height.equalToSuperview().multipliedBy(0.5)
                make.centerX.equalToSuperview()
                make.width.equalToSuperview()
            }
            
            trainingBar.snp.makeConstraints { make in
                make.bottom.equalToSuperview().multipliedBy(0.75)
                make.height.equalToSuperview().multipliedBy(0.5)
                make.centerX.equalToSuperview()
                make.width.equalToSuperview()
            }
        }
 
    }
    
    
    class BarChartView: CollectionView, UICollectionViewDataSource {
        
        var max: Int = 110
        var min: Int = 50
        var barWidth: CGFloat = 5.0
        
        var barDatas: [HeartBarData]? {
            
            didSet {
                
                self.reloadData()
            }
            
        }
        
        public override init() {
            
            let layout = UICollectionViewFlowLayout()
            layout.minimumLineSpacing = 0
            layout.minimumInteritemSpacing = 0
            layout.itemSize = CGSize(width: barWidth, height: 10)
            layout.scrollDirection = .horizontal
            
            super.init(frame: CGRect.zero, collectionViewLayout: layout)
            
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        var layout: UICollectionViewFlowLayout {
            return self.collectionViewLayout as! UICollectionViewFlowLayout
        }
        
        public override func makeUI() {
            super.makeUI()
            
            self.isScrollEnabled = false
            self.register(BarChartCollectionCell.self, forCellWithReuseIdentifier: BarChartCollectionCell.reuseIdentifier)
            self.dataSource = self
        }
        
        // MARK: - CollectionView Data Source
        public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            
            return barDatas?.count ?? 0
            
        }
        
        public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BarChartCollectionCell.reuseIdentifier, for: indexPath) as! BarChartCollectionCell
            
            cell.max = max
            cell.min = min
            cell.barWidth = barWidth
            cell.barData = barDatas?[indexPath.item]
            
            return cell
            
        }
        
        public override func layoutSubviews() {
            super.layoutSubviews()
            
            let layout = self.layout
            
            var cellWidth = barWidth
            if let barDatas = barDatas {
                var count = 48
                if barDatas.count < 2 {
                    count = 1
                } else {
                    count = barDatas.count
                }
                cellWidth = self.frame.width/CGFloat(count)
                
            }
            
            if layout.itemSize.height != self.frame.height || layout.itemSize.width != cellWidth {
                
                layout.itemSize = CGSize(width: cellWidth, height: self.frame.height)
                self.collectionViewLayout = layout
                self.reloadData()
            }
            
        }
        
    }
    
}



